package com.tb;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.tb.util.io.ImageDownLoadUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.nutz.ssdb4j.SSDBs;
import org.nutz.ssdb4j.spi.Response;
import org.nutz.ssdb4j.spi.SSDB;

import java.io.*;
import java.text.MessageFormat;
import java.util.*;

/**
 * ssdb 图片字节统计
 * Created by zhaoYuan
 *
 * @since 2017/12/1.
 */
public class SsdbImageAnalyze {
    private SSDB ssdb;
    String prefix = "JD_IMG_KEY";
    String startKey = "JD_IMG_KEY";
    String endKey = "JD_IMG_KEYhttp://cbu01.alicdn.com/img/ibank/2011/644/066/258660446_1732618106.jpg";
//    String endKey = "";
    short[] result = new short[2 * 1024 * 1024];
    Result analyzeResult = new Result();
    int pageSize = 1000;

    private  String PERSIST_DIR = "d:/jd";

    private int[] toAnalyzeImageSize= new int[]{
            2790,
            65536,
            9725,
            262144
    };

    public static void main(String[] args) throws IOException {
        SsdbImageAnalyze analyze = new SsdbImageAnalyze();
        analyze.init();
        analyze.pullData();
        analyze.destroy();
        analyze.persist2();

    }

    private boolean needAnalyze(int imageSize){
        for (int i : toAnalyzeImageSize) {
            if(i == imageSize) return true;
        }
        return false;
    }

    private void init() throws IOException {
        Properties properties = new Properties();
        properties.load(SsdbImageAnalyze.class.getClassLoader().getResourceAsStream("ssdb.properties"));
        String host = properties.getProperty("ssdb.host");
        Integer port = Integer.valueOf(properties.getProperty("ssdb.port"));
        Integer timeout = Integer.valueOf(properties.getProperty("ssdb.timeout"));
        PERSIST_DIR = properties.getProperty("analyze.persist.dir");
        pageSize = Integer.valueOf(properties.getProperty("analyze.pageSize"));
        prefix = properties.getProperty("analyze.prefix");
        endKey = properties.getProperty("analyze.endKey");
        startKey = prefix;
        System.out.println(MessageFormat.format("host={0}; PERSIST_DIR={1};pageSize={2};endKey={3};timeout=${4}",
                host,PERSIST_DIR,String.valueOf(pageSize),endKey,String.valueOf(timeout)));
        ssdb = SSDBs.simple(host, port, timeout);
    }

    private void destroy() throws IOException {
        ssdb.close();
    }

    public void persist() throws IOException {
        File dir = new File(PERSIST_DIR);
        if (!dir.exists()) dir.mkdirs();
        String fileName = "imgAnalyze.csv";
        File persistFile = new File(dir, fileName);
        if (!persistFile.exists()) persistFile.createNewFile();

        BufferedWriter fileWriter = new BufferedWriter(new FileWriter(persistFile));
        for (int i = 0; i < result.length; i++) {
            short count = result[i];
            if (count < 1) continue;
            String line = i +"," + count;
            fileWriter.write(line);
            fileWriter.newLine();
        }

        fileWriter.flush();
        fileWriter.close();
    }

    public void persist2() throws IOException {
        File dir = new File(PERSIST_DIR);
        if (!dir.exists()) dir.mkdirs();
        String fileName = "imgAnalyze2.csv";
        File persistFile = new File(dir, fileName);
        if (!persistFile.exists()) persistFile.createNewFile();

        BufferedWriter fileWriter = new BufferedWriter(new FileWriter(persistFile));
        for (Map.Entry<String, List<String>> entry : analyzeResult.result.entrySet()) {
            String line = entry.getKey() + "," + Joiner.on(",").join(entry.getValue());
            fileWriter.write(line);
            fileWriter.newLine();
        }

        fileWriter.flush();
        fileWriter.close();
    }

    private void pullData() {

        boolean hasNext = true;
         int page = 1;
        do {
            try {
                Response response = ssdb.scan(startKey, endKey, pageSize);
                System.out.println(" get page " + page++);
                hasNext = parseResult(result, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } while (hasNext);

    }

    private boolean parseResult(short[] result, Response response) {
        response.check();
        Map<String, String> strings = response.mapString();
        if (strings == null || strings.size() < 1) return false;
        for (Map.Entry<String, String> string : strings.entrySet()) {
            try {
                if (!string.getKey().startsWith(prefix)) return false;
                startKey = string.getKey();
                ImageInfo imageInfo = JSON.parseObject(string.getValue(), ImageInfo.class);
                imageInfo.setImgSource(string.getKey().replaceFirst(prefix,""));
                int imageSize = imageInfo.imageSize;
                if(!needAnalyze(imageSize))  continue;
                imageInfo.calcMd5();
                analyzeResult.add(imageInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    static class ImageInfo {
        private String picturePath;

        private String imgSource;

        private Date create_data;

        private int imageSize;

        private String md5;

        public String getPicturePath() {
            return picturePath;
        }

        public void setPicturePath(String picturePath) {
            this.picturePath = picturePath;
        }

        public Date getCreate_data() {
            return create_data;
        }

        public void setCreate_data(Date create_data) {
            this.create_data = create_data;
        }

        public int getImageSize() {
            return imageSize;
        }

        public void setImageSize(int imageSize) {
            this.imageSize = imageSize;
        }

        public String getMd5() {
            return md5;
        }

        public void setMd5(String md5) {
            this.md5 = md5;
        }

        public String getImgSource() {
            return imgSource;
        }

        public void setImgSource(String imgSource) {
            this.imgSource = imgSource;
        }

        public String getKey(){
            return imageSize + "_" + md5;
        }

        public void calcMd5(){
            byte[] bytes = ImageDownLoadUtils.downLoad(imgSource);
            md5 = DigestUtils.md5Hex(bytes);
        }
    }


    static class Result{
        private Map<String,List<String>> result = new HashMap<>();

        public void add(ImageInfo aa){
            if(result.containsKey(aa.getKey())){
                result.get(aa.getKey()).add(aa.getImgSource());
            }else {
                List<String> pics = new LinkedList<>();
                pics.add(aa.getImgSource());
                result.put(aa.getKey(),pics);
            }
        }
    }


}
